// Fill out your copyright notice in the Description page of Project Settings.

#include "UEMLAgents.h"
#include "RPCCommunicator.h"
#include "grpcpp/channel.h"
#include "grpcpp/create_channel.h"

communicator_objects::UnityInput MLAgents::RPCCommunicator::Initialize(communicator_objects::UnityOutput* unityOutput, communicator_objects::UnityInput& unityInput)
{
	m_isOpen = true;
	auto channel=grpc::CreateChannel("localhost:" + m_communicatorParameters.port, grpc::InsecureChannelCredentials());
	m_client = communicator_objects::UnityToExternal::NewStub(channel);
	Proto::UnityMessage resultMessage;
	Proto::UnityMessage inputMessage;
	auto resultStatus = m_client->Exchange(&clientContext,*WrapMessage(unityOutput,200),&resultMessage);
	m_client->Exchange(&clientContext, *WrapMessage(nullptr, 200), &inputMessage);
	unityInput = inputMessage.unity_input();
	return resultMessage.unity_input();
	
}

communicator_objects::UnityInput MLAgents::RPCCommunicator::Exchange(communicator_objects::UnityInput* input)
{
	throw std::logic_error("The method or operation is not implemented.");
}

void MLAgents::RPCCommunicator::Close()
{
	throw std::logic_error("The method or operation is not implemented.");
}

MLAgents::RPCCommunicator::RPCCommunicator(CommunicatorParameters communicatorParameters)
{
	m_communicatorParameters = communicatorParameters;
}

Proto::UnityMessage * MLAgents::RPCCommunicator::WrapMessage(Proto::UnityOutput * content, int status)
{
	auto message = new Proto::UnityMessage();
	auto header = new Proto::Header();
	header->set_status(status);
	message->set_allocated_header(header);
	message->set_allocated_unity_output(content);
	return message;
}
